﻿using LuShanTea.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LuShanTea.DTO;
using LuShanTea.Service.Entities;
using LuShanTea.Common;
using System.Data.Entity;

namespace LuShanTea.Service
{
    public class AdminUserService : IAdminUserService
    {
        private AdminUserDTO ToDTO(AdminUser en)
        {
            AdminUserDTO dto = new AdminUserDTO();
            dto.CreateDateTime = en.CreateDateTime;
            dto.Email = en.Email;
            dto.Gender = en.Gender;
            dto.Id = en.Id;
            dto.ImgSrc = en.ImgSrc;
            dto.Name = en.Name;
            dto.NickName = en.NickName;
            dto.PhoneNum = en.PhoneNumber;
            
            return dto;
        }

        public long AddNew(AdminUserAddUpdateDto par)
        {
            AdminUser en = new AdminUser();
            en.Email = par.Email;
            en.Gender = par.Gender;
            en.Salt = CommonHelper.GetSalt();
            en.HashPwd = CommonHelper.CalcMD5(par.PassWord + en.Salt);
            en.ImgSrc = par.ImgSrc;
            en.Name = par.Name;
            en.NickName = par.NickName;
            en.PhoneNumber = par.PhoneNum;
            //en.Roles
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var adminUser = bs.GetAll().SingleOrDefault(
                    e => e.Email == par.Email ||
                    e.NickName == par.NickName ||
                         e.PhoneNumber == par.PhoneNum);
                if (adminUser != null)
                {
                    throw new ArgumentException("邮箱、昵称或者电话已存在");
                }
                ctx.AdminUsers.Add(en);
                ctx.SaveChanges();
                return en.Id;
            }
        }

        public bool CheckLogin(string phoneNum, string pwd)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var en = bs.GetAll()
                    .SingleOrDefault(e => e.PhoneNumber == phoneNum);
                return en == null ? false : (en.HashPwd != CommonHelper.CalcMD5(pwd + en.Salt) ? false : true);
            }
        }

        public AdminUserDTO[] GetAll()
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                return bs.GetAll().AsNoTracking().ToList().Select(e => ToDTO(e)).ToArray();
            }
        }

        public AdminUserDTO GetById(long adminUserId)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var res = bs.GetById(adminUserId);
                return res == null ? null : ToDTO(res);
            }
        }

        public AdminUserDTO GetByPhoneNum(string phoneNum)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var res = bs.GetAll().SingleOrDefault(e => e.PhoneNumber == phoneNum);
                return res == null ? null : ToDTO(res);
            }
        }

        public bool HasPermission(long adminUserId, string permName)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var en = bs.GetById(adminUserId);
                if (en == null)
                {
                    throw new ArgumentException("找不到Id=" + adminUserId + "的管理员");
                }
                return en.Roles.SelectMany(e => e.Permissions).Any(e => e.Name == permName);
            }
        }

        public void MarkDelete(long adminUserId)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                bs.MakeDelete(adminUserId);
            }
        }

        public void Update(AdminUserAddUpdateDto par)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var en = bs.GetById(par.Id);
                if (en == null)
                {
                    throw new ArgumentException("找不到Id=" + par.Id + "的管理员");
                }
                en.Email = par.Email;
                en.Gender = par.Gender;
                if (!string.IsNullOrWhiteSpace(par.PassWord))
                {
                    en.HashPwd = CommonHelper.CalcMD5(par.PassWord + en.Salt);
                }
                en.ImgSrc = par.ImgSrc;
                en.Name = par.Name;
                en.NickName = par.NickName;
                en.PhoneNumber = par.PhoneNum;

                //TODO:检查数据是否重复

                ctx.SaveChanges();
            }
        }

        public void UpdatePwd(long adminUserId, string newPwd)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var en = bs.GetById(adminUserId);
                if (en == null)
                {
                    throw new ArgumentException("找不到Id=" + adminUserId + "的管理员");
                }
                en.HashPwd = CommonHelper.CalcMD5(newPwd + en.Salt);
                ctx.SaveChanges();
            }
        }

        public AdminUserDTO GetByEmail(string email)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var res = bs.GetAll().SingleOrDefault(e => e.Email == email);
                return res == null ? null : ToDTO(res);
            }
        }

        public AdminUserDTO GetByEmailOrPhone(string email, string phoneNum)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var res = bs.GetAll().SingleOrDefault(e => e.Email == email || e.PhoneNumber == phoneNum);
                return res == null ? null : ToDTO(res);
            }
        }

        public void LockAdminUser(long AdminUserId)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var admin = bs.GetById(AdminUserId);
                admin.LoginErrorCount = admin.LoginErrorCount + 1;
                admin.LastLoginErrorTime = DateTime.Now;
                ctx.SaveChanges();
            }
        }

        public void UnLockAdminUser(long AdminUserId)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var admin = bs.GetById(AdminUserId);
                admin.LoginErrorCount = 0;
                ctx.SaveChanges();
            }
        }

        public bool IsLock(long AdminUserId)
        {
            using (LuShanTeaContext ctx = new LuShanTeaContext())
            {
                BaseService<AdminUser> bs = new BaseService<AdminUser>(ctx);
                var admin = bs.GetById(AdminUserId);
                return (admin.LoginErrorCount >= 5 && (DateTime.Now.AddMinutes(-30) < admin.LastLoginErrorTime)) ? true : false;
            }
        }
    }
}
